﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

namespace CoD4_Helper
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Define a new instance of the GlobalKeyboardHook class, it doesn't start hooking keys
        /// </summary>
        GlobalKeyboardHook _gkh = new GlobalKeyboardHook();

        /// <summary>
        /// Instance of ProcessUtils class
        /// </summary>
        ProcessUtils _procUtils = new ProcessUtils();

        /// <summary>
        /// Global field to store if CoD4 is installed
        /// </summary>
        bool _IsCodInstalled = false;

        /// <summary>
        /// Global field to store if there are CoD4 user profiles
        /// </summary>
        bool _ProfilesDetected = false;

        /// <summary>
        /// The Config file of the active profile to perform operations on
        /// </summary>
        ConfigFile currentCfg;

        private void Form1_Load(object sender, EventArgs e)
        {
            InitUtils();
            InitializeUI();

            // Get OS Infos
            lblOsVersion.Text = OSUtils.GetOsVersion();

            // TODO enable hook only when COD is opened and "focused"
        }

        #region Private Methods Inizialize and ToggleButtons
        private void InitUtils()
        {
            OSUtils.DetectOS();
            Utils.SettingsManager.Inizialize();
            Utils.COD.InizializePaths();
        }

        /// <summary>
        /// Enable/disable controls on the form according to
        /// the installation of CoD.
        /// </summary>
        private void InitializeUI()
        {
            Utils.COD.ActiveProfileChanged += new Utils.COD.ActiveProfileEventHandler(COD_OnActiveProfileChange);


            _IsCodInstalled = Utils.COD.DetectCODInstallation();
            _ProfilesDetected = Utils.COD.DetectCODProfiles();

            if (_IsCodInstalled)
            {
                if (_ProfilesDetected)
                {
                    lblDetected.Text = "COD4 is currently installed";
                    lblDetected.BackColor = Color.LightGreen;

                    // Populate the combo with profiles
                    comboProfiles.DataSource = Utils.COD.GetProfiles();

                    // Populate the combo with Mods
                    comboMod.DataSource = Utils.COD.GetMods();

                    // Get active profile
                    lblActiveProfile.Text = Utils.COD.ActiveProfile;

                    // The config of the active profile
                    string cfgPath = Path.Combine(Utils.COD.ProfilesDir, Utils.COD.ActiveProfile, "config_mp.cfg");

                    currentCfg = new ConfigFile(cfgPath);

                    currentCfg.OnLoad += new ConfigFile.NewConfigEventHandler(currentCfg_NewConfig);
                    
                    ToggleButtons(true);
                }
                else
                {
                    lblDetected.Text = "COD4 is installed, could not locate profiles folder";
                    lblDetected.BackColor = Color.Yellow;
                    ToggleButtons(false);
                }
            }
            else
            {
                lblDetected.Text = "COD4 is not installed!";
                lblDetected.BackColor = Color.Yellow;
                ToggleButtons(false);
            }
        }

        void currentCfg_NewConfig(object sender, EventArgs e)
        {
            lblCfgSize.Text = currentCfg.GetSize();
            lblCfgLines.Text = currentCfg.GetNumOfLines().ToString();
        }

        
        
        /// <summary>
        /// Toggles the Enable state of every buttons on the form
        /// </summary>
        private void ToggleButtons(bool areVisible)
        {
            var controls = this.Controls;
            // loop each button in the form 
            foreach (var control in controls)
            {
                if (control is Button)
                {
                    //if ((control as Button).Name != "btnCustomInstDir")
                    //{
                    (control as Button).Enabled = areVisible;
                    //}
                }
            }

            GroupBox gBox = new GroupBox();
            // loop each button in each GroupBoX
            foreach (var control in controls)
            {
                if (control is GroupBox)
                {
                    gBox = (GroupBox)control;

                    foreach (var btn in gBox.Controls)
                    {
                        if (btn is Button)
                        {
                            (btn as Button).Enabled = areVisible;
                        }
                    }
                }
            }
        }
        #endregion
        
        #region GlobalKeyboardHook.cs
        /// <summary>
        /// Activate Low Level Hooks for selected Keyboard keys
        /// </summary>
        /// <param name="keysToHook">Collection of keys to hook for</param>
        private void ActivateHooks(IEnumerable<Keys> keysToHook)
        {
            if (keysToHook != null)
            {
                foreach (var key in keysToHook)
                {
                    _gkh.HookedKeys.Add(key);
                }

                _gkh.Hook();

                _gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
                _gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
            }
            
        }

        /// <summary>
        /// Disable the Low Level hooks
        /// </summary>
        private void DeactivateHook()
        {
            _gkh.UnHook(); // GlobalKeyboardHook.cs
        }
        
        // KeyDown event
        void gkh_KeyDown(object sender, KeyEventArgs e)
        {
            lblHookedKey.Text = e.KeyCode.ToString();

            // suppress windows buttons
            if (e.KeyCode == Keys.LWin || e.KeyCode == Keys.RWin)
            {
                if (checkWin.Checked)
                    e.Handled = true; // suppress the key
            }

            if (e.KeyCode == Keys.NumPad1)
            {
                UserInteraction.KeyboardInput.SendKey(0xDC); // OEM_5 (| \)
                SendKeys.Send("quit{ENTER}");
                e.Handled = true;
            }

        }

        // KeyUp event
        void gkh_KeyUp(object sender, KeyEventArgs e)
        {
            // suppress windows buttons
            if (e.KeyCode == Keys.LWin || e.KeyCode == Keys.RWin)
                if (checkWin.Checked)
                    e.Handled = true; // suppress the key
        }

        // Enable/Disable Hooks through checkboxes
        private void checkHook_CheckedChanged(object sender, EventArgs e)
        {
            if (checkHook.Checked)
            {
                List<Keys> keys = new List<Keys>() { /*Keys.NumPad1,*/ Keys.LWin, Keys.RWin };
                ActivateHooks(keys);
                checkWin.Enabled = true; ;
            }
            else
            {
                DeactivateHook();
                checkWin.Checked = false;
                checkWin.Enabled = false;
            }
        }
        #endregion


        #region Custom Events (subscription)
        void COD_OnActiveProfileChange(object sender, Utils.ActiveProfileEventArgs e)
        {
            lblActiveProfile.Text = e.ProfileName;
        } 
        #endregion

        // switch the profile
        private void btnSelectProfile_Click(object sender, EventArgs e)
        {
            Utils.COD.ActiveProfile = comboProfiles.SelectedItem.ToString();
        }

        // fast connect button
        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(txtIP.Text))
                Utils.COD.LaunchCoD("connect " + txtIP.Text);
        }

        // open the profiles folder
        private void btnProfileFolder_Click(object sender, EventArgs e)
        {
            _procUtils.StartExplorer(Utils.COD.ProfilesDir);
        }

        // open the installation folder
        private void btnInstallFolder_Click(object sender, EventArgs e)
        {
            _procUtils.StartExplorer(Utils.COD.InstallationDir);
        }

        // Launch COD
        private void btnLaunch_Click(object sender, EventArgs e)
        {
            if (comboMod.SelectedItem.ToString() == "None")
            {
                Utils.COD.LaunchCoD();
            }
            else
            {
                Utils.COD.LaunchCoDMod(comboMod.SelectedItem.ToString());
            }
        }



        #region Tool Strip Menu Items
        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SettingsForm frm = new SettingsForm();
            frm.ShowDialog();

            InitializeUI();
        }

        private void authorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Developed by: Cesare Puliatti \n\nTwitter: @crushjz");
        }

        private void versionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // TODO add an About Form
            MessageBox.Show("Version: " + Application.ProductVersion + " Beta");
        }
        #endregion

        private void btnEditCfg_Click(object sender, EventArgs e)
        {
            // Edit the current active profile Config
            string cfgPath = Path.Combine(Utils.COD.ProfilesDir, Utils.COD.ActiveProfile, "config_mp.cfg");

            CfgEditorForm frm = new CfgEditorForm(cfgPath);
            frm.ShowDialog();
        }

        

        
    }
}
